package util;

import csvreader.CsvReader;
import org.apache.log4j.Logger;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * User: pradeep
 * Date: Aug 13, 2010
 * Time: 6:37:42 PM
 * Utility class for "Chemical & biochemical map" Application (actual logic implemented here)
 */
public class KEGGPairUtil{

    Logger gLogger = Logger.getLogger(KEGGPairUtil.class);

    private static KEGGPairUtil util = null;
    private static List KEGGPairList = null;

    /**
     * get instance of util class
     * @return
     */
    public static KEGGPairUtil getInstance(){
        if(util == null){
            util = new KEGGPairUtil();
        }
        return util;
    }

    /**
     * Load KEGG-R Pair List 
     */
    private void setPairList(){
       gLogger.info("comming into setPairList method of KEGGPairUtil");
       try{
        if(KEGGPairList == null){
            KEGGPairList = new ArrayList();
           
            BufferedReader in = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/kegg-rpairlinks.txt")));

            String string="";
            while( (string = in.readLine()) != null) {
                string = new String(string.getBytes(),"UTF-8");
                KEGGPairList.add(string);
            }
        }
       }catch(Exception e){
            gLogger.error(e.getMessage(),e);
       }
       gLogger.info("out from setPairList method of KEGGPairUtil"); 
    }

    /**
     * to get the list of KEGG-R Pair
     * @return
     */
    public List getKEGGPairList(){
        gLogger.info("comming into getKEGGPairList method of KEGGPairUtil");
        if(KEGGPairList == null){
          setPairList();  
        }
        gLogger.info("out from getKEGGPairList method of KEGGPairUtil");
        return this.KEGGPairList;
    }

    /**
     * to load KEGG-R Pair List
     */
    public void loadKEGGPairList(){
        gLogger.info("comming into loadKEGGPairList method of KEGGPairUtil");
        if(KEGGPairList == null){
          setPairList();
        }
        gLogger.info("out from loadKEGGPairList method of KEGGPairUtil");
    }

    /**
     * process method to calculate chemical similarity
     * @param data
     * @return
     */
    public List<String> processkeggReactionPair(String data)
    {
        List<String> lArrList = null;
        try
        {
            char delimiter = ChemSimilarityUtil.getInstance().getDelimiter(data);
            StringReader strReader = new StringReader(data);
            CsvReader reader = new CsvReader(strReader,delimiter);
            lArrList = getResult(reader);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return lArrList;
    }

    int colCount = 0;
    private List keggIdList = null;
    private Map keggCIdMap=null;

    /**
     * to prepare required parameters for processing than call actual process method 
     * @param reader
     * @return
     */
    private List<String>  getResult(CsvReader reader) {
        List<String> lArrList = new ArrayList<String>();
        try
        {
            reader.readRecord();
            colCount = reader.getColumnCount();
            gLogger.info("colCount :: "+colCount);

            keggIdList = new ArrayList();
            keggCIdMap = new HashMap();
            
            int rowId = 0 ;
            
            int cidColumnIndex = 0;
            int keggColumnIndex = 1;
            String keggData="";
            String cidData="";
            do{
                keggData="";
                cidData="";
                for(int colId=0; colId<colCount ; colId++ )
                {
                    // if the data file has Titled Column as "KEGG" or "PubChem"
                    if( reader.get(colId).trim().equalsIgnoreCase("KEGG") ){
                        keggColumnIndex = colId;
                    }else if( reader.get(colId).trim().equalsIgnoreCase("PubChem") ){ // CID
                        cidColumnIndex = colId;
                    }else{
                        // store keggData if keggColumnIndex is equals to current column index
                        if(keggColumnIndex == colId){
                           keggData = reader.get(colId).trim(); 
                        }else if(cidColumnIndex == colId){ // store cidData if keggColumnIndex is equals to current column index
                           cidData = reader.get(colId).trim();
                        }
                        
                    }
                }

                // prepare unique keggIdList and keggCIdMap
                if(keggData!=null && keggData.trim().length()>0 && !keggIdList.contains(keggData)){
                   keggIdList.add(keggData);

                   if(cidData!=null && cidData.trim().length()>0){
                     keggCIdMap.put(keggData,cidData);  
                   }

                }
                rowId++;
            }while(reader.readRecord());
            reader.close();

//            gLogger.info("================ Input =============");
//            gLogger.info("keggIdList :: "+keggIdList);
//            gLogger.info("keggCIdMap :: "+keggCIdMap);

            List KEGGPairList = KEGGPairUtil.getInstance().getKEGGPairList();
//            gLogger.info("\n\n\nsize :: "+KEGGPairList.size());
            lArrList = processKEGGPairs(KEGGPairList);
//            gLogger.info("\n\n\nlArrList :: "+lArrList);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return lArrList;
    }


    /**
     * to preapre result
     * @param KEGGPairList
     * @return
     */
    private List<String> processKEGGPairs(List KEGGPairList){
        gLogger.info("comming into processKEGGPairs method of KEGGPairUtil");
        List resultList = new ArrayList();
        String[] keggIds = null;
        if(KEGGPairList!=null && KEGGPairList.size()>0){
            for(int index=0;index<KEGGPairList.size();index++){
               keggIds =  KEGGPairList.get(index).toString().split("\t");
               if(keggIds.length > 1 ){

                   // Replace KEGG Id's with corresponding CId's
                   if( keggIdList.contains(keggIds[0]) && keggIdList.contains(keggIds[1]) ){
                     resultList.add(keggCIdMap.get(keggIds[0])+"\t"+keggCIdMap.get(keggIds[1]));  
                   }
               }
            }
        }
        gLogger.info("out from processKEGGPairs method of KEGGPairUtil");
        return resultList;
    }

    /**
     * to prepare KEGGReaction Pair
     * @param krpList
     * @return
     */
    public String prepareKEGGReactionPair(List<String> krpList){
        String resultStream = "";
        String[] cols = null;
        for (String string : krpList) {
            cols = string.split("\t");
            if( cols!=null && cols.length>1 ){
              if(resultStream.trim().length()==0){
                  resultStream = cols[0] + "\tkrp\t"+ cols[1];
              }else{
                  resultStream += "\n" + cols[0] + "\tkrp\t"+ cols[1];
              }
            }
        }

        return resultStream;
    }

    /**
     * to prepare Edge Attribute
     * @param edgeAttributeStr
     * @param krpList
     * @return
     */
    public String prepareEdgeAttribute(String edgeAttributeStr,List<String> krpList){
        String resultStream = "";
        String[] cols = null;

        if(edgeAttributeStr!=null && edgeAttributeStr.trim().length()>0){
            resultStream = edgeAttributeStr;
        }

        for (String string : krpList) {
            cols = string.split("\t");
            if( cols!=null && cols.length>1 ){
              if(resultStream.trim().length()==0){
                  //resultStream = cols[0] + " (krp) "+ cols[1]+"\t1";
            	  resultStream = cols[0] + "\tkrp\t"+ cols[1];
              }else{
                  resultStream += "\n" + cols[0] + "\tkrp\t"+ cols[1];
              }
            }
        }

        return resultStream;
    }

}
